#include "serial.h"

Serial::Serial()
{
    // 初始化串口
    m_serialPort = new QSerialPort;
    m_serialPortInfo = new QSerialPortInfo;
    m_timer = new QTimer(this);

    // 当计时终止，处理读取到的数据，发送读取数据信号
    connect(m_timer,SIGNAL(timeout()),this,SLOT(timerUpdate()));
    connect(m_timer,SIGNAL(timeout()),this,SIGNAL(readBufSignal()));
 }

/**
 * @brief Serial::scanSerial
 * 扫描可用串口
 * @return
 */
QStringList Serial::scanSerial()
{
    QStringList serialStrList;

    // 读取串口信息
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        QSerialPort serial;
        serial.setPort(info);
        if(serial.open(QIODevice::ReadWrite)){
            serialStrList.append(info.portName());
        }
        serial.close();
    }

    return serialStrList;
}

/**
 * @brief Serial::open
 *
 * 打开串口
 * @param serialName 串口名
 * @param baudRate 波特率
 * @param databits  数据位
 * @param parity    校验位
 * @param stopBits  停止位
 * @param flowControl   流控制
 * @return
 */
bool Serial::open(QString serialName, int baudRate, QSerialPort::DataBits databits, QSerialPort::Parity parity, QSerialPort::StopBits stopBits, QSerialPort::FlowControl flowControl)
{
    // 设置串口名
    m_serialPort->setPortName(serialName);
    // 打开串口(以读写方式)
    if(m_serialPort->open(QIODevice::ReadWrite))
    {
        m_serialPort->setBaudRate(baudRate); // 设置波特率
        m_serialPort->setDataBits(databits); // 设置数据位(数据位为8位)
        m_serialPort->setParity(parity); // 设置校验位(无校验位)
        m_serialPort->setStopBits(stopBits); // 设置停止位(停止位为1)
        m_serialPort->setFlowControl(flowControl); // 设置流控制(无数据流控制)

        // 当下位机中有数据发送过来时就会响应这个槽函数
        connect(m_serialPort, SIGNAL(readyRead()), this, SLOT(readData()));
        // 当下位机中有数据发送过来时就会触发这个信号，以提示其它类对象
        connect(m_serialPort, SIGNAL(readyRead()), this, SIGNAL(readSignal()));

        return true;
    }

    return false;
}

/**
 * @brief Serial::close
 * 关闭串口
 */
void Serial::close()
{
    m_serialPort->clear();
    m_serialPort->close();
}

/**
 * @brief Serial::standardBaudRates
 *
 * 返回QStringList格式的波特率列表
 * @return
 */
QStringList Serial::standardBaudRates()
{
    QStringList sBRs;
    foreach(qint32 baud,m_serialPortInfo->standardBaudRates()){
        sBRs << QString::number(baud);
    }
    return sBRs;
}

/**
 * @brief Serial::sendData
 * 发送数据给下位机
 * @param sendData
 */
void Serial::sendData(QByteArray &sendData)
{
    // 发送数据帧
    m_serialPort->write(sendData);
}

/**
 * @brief Serial::readData
 * 读取从下位机发来的数据
 */
void Serial::readData()
{
    // 将下位机发来数据存储在数据缓冲区
    m_timer->start(readTime);
    m_tmpBuf.append(m_serialPort->readAll());
}

/**
 * @brief Serial::getReadBuf
 * 返回缓冲区数据
 * @return
 */
QByteArray Serial::getReadBuf()
{
    return m_readBuf;
}

/**
 * @brief Serial::clearReadBuf
 * 清空缓冲区
 */
void Serial::clearReadBuf()
{
    m_readBuf.clear();
}

/**
 * @brief Serial::timerUpdate
 * QTimer计时结束触发，复制并清空临时缓冲区
 */
void Serial::timerUpdate()
{
    m_timer->stop();
    m_readBuf = m_tmpBuf;
    m_tmpBuf.clear();
}

/**
 * @brief Serial::setReadTime
 * 设置读取时长
 * @param mesc
 */
void Serial::setReadTime(int mesc)
{
    readTime = mesc;
}

/**
 * @brief Serial::getReadTime
 * 获取当前读取时长
 * @return
 */
int Serial::getReadTime()
{
    return readTime;
}
